#include "my_console.h"
#include "utf8.h"

#include <stdio.h>

void DrawCenterStrInRectUTF8(const char *str, uint64_t leng, STRect *rect)
{
    uint8_t *displayStr = (uint8_t *)str;
    uint8_t *oneLineChars = NULL;
    oneLineChars = malloc((rect->width * 4 + 1) * sizeof(uint8_t));
    uint32_t *linesEndPos = NULL;
    linesEndPos = malloc(rect->height * sizeof(uint32_t));
    memset(linesEndPos, 0, rect->height * sizeof(uint32_t));

    uint32_t charWidth = UTF8GetStrShowWidth(displayStr);
    size_t startPos = 0;
    uint16_t needLines = 0;
    while(1) {
        size_t endPos = UTF8FindEndPosForContainerWidth(str, startPos, rect->width);
        if (endPos > leng) {
            printf("error break endPos: %lld, length: %lld\n", endPos, leng);
            return;
        }
        startPos = endPos;
        linesEndPos[needLines] = (uint32_t)endPos;
        needLines++;
        if (!displayStr[endPos] || needLines >= rect->height)
        {
            // printf("break endPos: %d, needLines: %d\n", endPos, needLines);
            break;
        }
    }

    uint16_t startY = (rect->height - needLines) / 2;

    for (uint8_t i = 0; i < needLines; i++) {
        uint64_t charSize = 0;
        uint16_t showWidth = 0;
        if (i == 0) {
            charSize = linesEndPos[i];
            strncpy((char *)oneLineChars, displayStr, charSize);
            showWidth = UTF8GetShowLengthByStartAndEndPos(displayStr, 0, linesEndPos[i]);
            oneLineChars[charSize] = '\0';
        } else {
            charSize = linesEndPos[i] - linesEndPos[i - 1];
            strncpy((char *)oneLineChars, displayStr + linesEndPos[i - 1], charSize);
            showWidth = UTF8GetShowLengthByStartAndEndPos(displayStr, linesEndPos[i - 1], linesEndPos[i]);
            oneLineChars[charSize] = '\0';
        }
        if (i == needLines - 1 && leng > linesEndPos[needLines - 1]) {
            int pos = 0;
            int charWidth = 0;
            pos = linesEndPos[i];
            while(charWidth < 3) {
                pos = UTF8FindPreviousCharStartPos(displayStr, pos);
                uint8_t showlen = UTF8GetCharShowWidth(displayStr[pos]);
                charWidth += showlen;
            }
            oneLineChars[pos] = '.';
            oneLineChars[pos + 1] = '.';
            oneLineChars[pos + 2] = '.';
            oneLineChars[pos + 3] = '\0';
        }
        // UTF8GetShowLengthByStartAndEndPos(displayStr, 0, linesEndPos[i]);
        uint16_t startX = (rect->width - showWidth) / 2; // TODO showWidth 计算有误
        DrawStrAtPos((uint16_t)startX, (uint16_t)startY++, oneLineChars);
        //printf("%s\n", oneLineChars);
    }

    free(oneLineChars);
    free(linesEndPos);
    return;
}

void StoreScreen()
{
    vt_store_screen();
}

void RestoreScreen()
{
    vt_restore_screen();
}

void EnableCursor()
{
    vt_show_cursor();
}

void DisEnableCursor()
{
    vt_hide_cursor();
}

void MoveCursorTo(uint16_t x, uint16_t y)
{
    vt_move_to(y, x);
}

void SetBgColor(vt_back_color bgColor)
{
    vt_set_bg_color(bgColor);
}

void SetFgColor(vt_fore_color fgColor)
{
    vt_set_font_color(fgColor);
}

void FillBox(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
    vt_fill_box(y, x, height, width, ' ');
}

void RenderBox(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
    vt_draw_box(y, x, height, width, '-', '|', '+');
}

void MoveUp(uint16_t l)
{
    vt_move_up(l);
}

void MoveDown(uint16_t l)
{
    vt_move_down(l);
}

void MoveRight(uint16_t l)
{
    vt_move_right(l);
}

void MoveLeft(uint16_t l)
{
    vt_move_left(l);
}

void DrawStrAtPos(uint16_t x, uint16_t y, char* str)
{
    vt_draw_str_at(y, x, str);
}

void DrawHorizontalLine(uint16_t x, uint16_t y, uint16_t l)
{
    vt_draw_hline(y, x, l, '-');
}

void DrawVerticalLine(uint16_t x, uint16_t y, uint16_t l)
{
    vt_draw_vline(y, x, l, '|');
}